/*
 * Copyright (C) 2004, Velocityme Partnership
 * StateMachineActionForm.java
 *
 * Created on 19 October 2004, 06:26
 */

package com.velocityme.www.actionforms;

import com.velocityme.entity.Role;
import com.velocityme.entity.Transition;
import com.velocityme.session.KeyLocal;
import com.velocityme.session.RoleLocal;
import com.velocityme.session.StateLocal;
import com.velocityme.session.StatusLocal;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;

/**
 *
 * @author  Robert
 */
public class StateMachineActionForm extends ActionForm {
    
    public class InternalTransition implements Serializable {
        private Long transitionId;
        private Long sourceStateId;
        private Long destinationStateId;
        private Long statusId;
        private boolean ownerResponsible = false;
        private boolean userResponsible = false;
        private Long[] assignedRoleIds;
            
        public Long getTransitionId() { return transitionId; }
        public void setTransitionId(Long transitionId) { this.transitionId = transitionId; }
        public Long getSourceStateId() { return sourceStateId; }
        public void setSourceStateId(Long sourceStateId) { this.sourceStateId = sourceStateId; }
        public Long getDestinationStateId() { return destinationStateId; }
        public void setDestinationStateId(Long destinationStateId) { this.destinationStateId = destinationStateId; }
        public Long getStatusId() { return statusId; }
        public void setStatusId(Long statusId) { this.statusId = statusId; }
        public boolean isOwnerResponsible() { return ownerResponsible; }
        public void setOwnerResponsible(boolean ownerResponsible) { this.ownerResponsible = ownerResponsible; }
        public boolean isUserResponsible() { return userResponsible; }
        public void setUserResponsible(boolean serResponsible) { this.userResponsible = serResponsible; }
        public Long[] getAssignedRoleIds() { return assignedRoleIds; }
        public void setAssignedRoleIds(Long[] assignedRoleIds) { this.assignedRoleIds = assignedRoleIds; }
    }
    
    private ArrayList<InternalTransition> m_transitionList = new ArrayList<InternalTransition>();
    private int m_selectedValue = 0;
    private String m_cmd="";
    
    @Override
    public void reset(ActionMapping mapping, javax.servlet.http.HttpServletRequest request) {
        for (InternalTransition transition: m_transitionList) {
            transition.setOwnerResponsible(false);
            transition.setUserResponsible(false);
            transition.setAssignedRoleIds(new Long[0]);
        }
    }
    
    public void setCmd(int index, String value) {
        m_selectedValue = index;
        m_cmd = value;
    }
    
    public String getCmd(int index) {
        return m_cmd;
    }
    
    public String getCmd() {
        return m_cmd;
    }
    
    public int getIndex() {
        return m_selectedValue;
    }
    
    public void setTransitions(Collection<Transition> transitions) {
        m_transitionList.clear();
        for (Transition transition: transitions) {
            InternalTransition it = new InternalTransition();
            it.transitionId = transition.getId();
            it.sourceStateId = transition.getSourceState().getId();
            it.destinationStateId = transition.getDestinationState().getId();
            it.statusId = transition.getStatus().getId();
            it.ownerResponsible = transition.isOwnerResponsible();
            it.userResponsible = transition.isUserResponsible();
            it.assignedRoleIds = new Long[transition.getResponsibleRoles().size()];
            int i = 0;
            for (Role role: transition.getResponsibleRoles()) {
                it.assignedRoleIds[i] = role.getId();
                i++;
            }
            m_transitionList.add(it);
        }
    }
    
    public Collection<Transition> getTransitions(KeyLocal key) {
        Collection<Transition> transitions = new ArrayList<Transition>();
        StateLocal stateBean = lookupStateBean();
        StatusLocal statusBean = lookupStatusBean();
        RoleLocal roleBean = lookupRoleBean();
        for (InternalTransition it: m_transitionList) {
            Transition transition = new Transition(it.isOwnerResponsible(), it.isUserResponsible());
            if (it.getTransitionId() != null)
                transition.setId(it.getTransitionId());
            transition.setSourceState(stateBean.findState(key, it.getSourceStateId()));
            transition.setDestinationState(stateBean.findState(key, it.getDestinationStateId()));
            transition.setStatus(statusBean.findStatus(key, it.getStatusId()));
            Collection<Role> assignedRoleValues = new ArrayList<Role>();
            for (Long roleId: it.getAssignedRoleIds()) {
                assignedRoleValues.add(roleBean.findRole(key, roleId));
            }
            transition.setResponsibleRoles(assignedRoleValues);
            transitions.add(transition);
        }
        return transitions;
    }
    
    public boolean processCmd() {
        if (m_cmd.equals("Add")) {
            InternalTransition transition = new InternalTransition();
            m_transitionList.add(transition);
            return true;
        }
        if (m_cmd.equals("Delete")) {
            m_transitionList.remove(m_selectedValue);
            return true;
        }
        return false;
    }
    
    public ArrayList<InternalTransition> getTransitionList() {
        return m_transitionList;
    }
    
    public void setTransitionList(ArrayList<InternalTransition> transitionList) {
        m_transitionList = transitionList;
    }
    
    private StateLocal lookupStateBean() {
        try {
            Context c = new InitialContext();
            return (StateLocal) c.lookup("java:comp/env/StateBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private StatusLocal lookupStatusBean() {
        try {
            Context c = new InitialContext();
            return (StatusLocal) c.lookup("java:comp/env/StatusBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }

    private RoleLocal lookupRoleBean() {
        try {
            Context c = new InitialContext();
            return (RoleLocal) c.lookup("java:comp/env/RoleBean");
        } catch (NamingException ne) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
            throw new RuntimeException(ne);
        }
    }
    
}
